﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Controller2.Models;

namespace Controller2.BLL
{
    public class JobBll
    {
        public static Job GetJob(ControllerBDModelContainer db, int id)
        {
            return db.Job.FirstOrDefault(c => c.IdJob == id);
        }

        public static IEnumerable<Job> GetAllJobs(ControllerBDModelContainer db)
        {
            return (from c in db.Job orderby c.DataCadastro select c).OrderBy(c => c.DataCadastro).ToList();
        }

        public static Dictionary<string, int> PreencheComboStatus()
        {
            return FuncoesAuxiliaresBll.PreencheComboStatus();
        }

        public static Dictionary<string, int> PreencheComboEtapa()
        {
            return FuncoesAuxiliaresBll.PreencheComboEtapa();
        }

        public static string GetStatus(int status)
        {
            return FuncoesAuxiliaresBll.GetStatus(status);
        }

        public static string GetEtapa(int etapa)
        {
            return FuncoesAuxiliaresBll.GetEtapa(etapa);
        }

        public static DataTable Relatorios(ControllerBDModelContainer db, int codigo, string dataInicial, string dataFinal, bool cliente = false, bool campanha = false)
        {
            IEnumerable<Job> lista;
            if (codigo > 0 && !cliente && !campanha)
            {
                lista = (from c in db.Job
                         where c.IdJob == codigo
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }
            else if (codigo > 0 && cliente && !campanha)
            {
                lista = (from c in db.Job
                         where c.IdCliente == codigo
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }
            else if (codigo > 0 && !cliente && campanha)
            {
                lista = (from c in db.Job
                         where c.IdCampanha == codigo
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }
            else if (!string.IsNullOrWhiteSpace(dataInicial))
            {
                var di = Convert.ToDateTime(dataInicial);
                var df = Convert.ToDateTime(dataFinal);
                lista = (from c in db.Job
                         where c.DataInicio >= di && c.DataConclusao <= df
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }
            else
            {
                lista = (from c in db.Job
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }

            var dt = new DataTable();
            dt.Columns.Add("DataCadastro", typeof(DateTime));
            dt.Columns.Add("IdJob", typeof(Int32));
            dt.Columns.Add("Status", typeof(String));
            dt.Columns.Add("Descricao", typeof(String));
            dt.Columns.Add("IdCliente", typeof(Int32));
            dt.Columns.Add("IdCampanha", typeof(Int32));
            dt.Columns.Add("NomePessoa", typeof(String));
            dt.Columns.Add("Nome", typeof(String));
            dt.Columns.Add("IdMidia", typeof(Int32));
            dt.Columns.Add("Valor", typeof(Decimal));
            dt.Columns.Add("IdFuncionario", typeof(Int32));
            dt.Columns.Add("IdFreelancer", typeof(Int32));

            foreach (Job j in lista)
            {
                DataRow r = dt.NewRow();
                r["DataCadastro"] = j.DataCadastro;
                r["IdJob"] = j.IdJob;
                r["Status"] = j.Status;
                r["Descricao"] = j.Descricao;
                r["IdCliente"] = j.IdCliente;
                r["IdCampanha"] = j.IdCampanha;
                r["NomePessoa"] = j.Cliente.NomePessoa;
                r["Nome"] = j.Campanha.Nome;
                r["IdMidia"] = j.IdMidia;
                r["Valor"] = j.Midia.Valor;
                r["IdFuncionario"] = j.IdFuncionario == null ? 0 : j.IdFuncionario;
                r["IdFreelancer"] = j.IdFreelancer == null ? 0 : j.IdFuncionario; ;
                dt.Rows.Add(r);
            }
            return dt;
        }

        public static DataTable RelatoriosCampanhas(ControllerBDModelContainer db, int codigo, string dataInicial, string dataFinal)
        {
            IEnumerable<Job> lista;
            if (codigo > 0)
            {
                lista = (from c in db.Job
                         where c.IdCampanha == codigo
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }
            else if (!string.IsNullOrWhiteSpace(dataInicial))
            {
                var di = Convert.ToDateTime(dataInicial);
                var df = Convert.ToDateTime(dataFinal);
                lista = (from c in db.Job
                         where c.Campanha.DataInicio >= di && c.Campanha.DataFim <= df
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }
            else
            {
                lista = (from c in db.Job
                         orderby c.DataCadastro
                         select c
                         ).OrderBy(c => c.DataCadastro).ToList();
            }

            var dt = new DataTable();
            dt.Columns.Add("DataCadastro", typeof(DateTime));
            dt.Columns.Add("IdJob", typeof(Int32));
            dt.Columns.Add("Status", typeof(String));
            dt.Columns.Add("Descricao", typeof(String));
            dt.Columns.Add("IdCliente", typeof(Int32));
            dt.Columns.Add("IdCampanha", typeof(Int32));
            dt.Columns.Add("NomePessoa", typeof(String));
            dt.Columns.Add("Nome", typeof(String));
            dt.Columns.Add("IdMidia", typeof(Int32));
            dt.Columns.Add("Valor", typeof(Decimal));
            dt.Columns.Add("IdFuncionario", typeof(Int32));
            dt.Columns.Add("IdFreelancer", typeof(Int32));

            foreach (Job j in lista)
            {
                DataRow r = dt.NewRow();
                r["DataCadastro"] = j.DataCadastro;
                r["IdJob"] = j.IdJob;
                r["Status"] = j.Status;
                r["Descricao"] = j.Descricao;
                r["IdCliente"] = j.IdCliente;
                r["IdCampanha"] = j.IdCampanha;
                r["NomePessoa"] = j.Cliente.NomePessoa;
                r["Nome"] = j.Campanha.Nome;
                r["IdMidia"] = j.IdMidia;
                r["Valor"] = j.Midia.Valor;
                r["IdFuncionario"] = j.IdFuncionario == null ? 0 : j.IdFuncionario;
                r["IdFreelancer"] = j.IdFreelancer == null ? 0 : j.IdFuncionario; ;
                dt.Rows.Add(r);
            }
            return dt;
        }

        public static bool SalvarJob(ControllerBDModelContainer db, Job j)
        {
            db.Connection.Open();
            using (var transaction = db.Connection.BeginTransaction())
            {
                try
                {
                    // inclui ou altera o job
                    if (j.IdJob > 0)
                    {
                        db.Job.ApplyCurrentValues(j);
                        db.SaveChanges();
                    }
                    else
                    {
                        db.Job.AddObject(j);
                        db.SaveChanges();
                        if (j.GerarContaReceber)
                        {
                            // inclui a entrada
                            var entrada = new Entrada();
                            entrada.DataPrevista = j.DataConclusao;
                            entrada.IdMidia = j.IdMidia;
                            entrada.ValorPrevisto = MidiaBll.GetValorMidia(db, j.IdMidia);
                            entrada.Descricao = "Lançamento referente ao Job de Código: " + j.IdJob + ", cadastrado no dia: " + j.DataCadastro.ToShortDateString();
                            entrada.Job = j;
                            db.AddObject("Entrada", entrada);
                            db.SaveChanges();
                        }
                    }
                    transaction.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    throw ex;
                }
                finally
                {
                    db.Connection.Close();
                }
            }
        }

        /// <summary>
        /// Faz o autocomplete do campo de texto de pesquisa
        /// </summary>
        /// <param name="db">Contexto de dados</param>
        /// <param name="filtro">Valor do filtro (combobox)</param>
        /// <param name="termoPesquisa">Termo da pesquisa (valor digitado)</param>
        /// <param name="numeroLinhas">Número de registros a serem mostrados</param>
        /// <returns></returns>
        public static IEnumerable<string> AutoComplete(ControllerBDModelContainer db, int filtro, string termoPesquisa, int numeroLinhas)
        {
            IEnumerable<string> resultado;
            int codigo = 0;
            if (filtro == 1)
            {
                if (!int.TryParse(termoPesquisa, out codigo))
                {
                    filtro = 2;
                }
            }
            switch (filtro)
            {
                default:
                    resultado = (from c in db.Job.ToList()
                                 where c.IdJob >= codigo
                                 select c.IdJob.ToString()).Distinct();
                    break;
                case 2:
                    resultado = (from c in db.Job.ToList()
                                 where c.DataCadastro.ToShortDateString().Contains(termoPesquisa)
                                 select c.DataCadastro.ToShortDateString()).Distinct();
                    break;
            }
            return resultado.Take(numeroLinhas);
        }
    }
}